﻿using System;
using System.Collections.Generic;
using System.Text;
using HardwareLibrary.ComLibrary;
using HardwareLibrary.LogLibrary;

namespace HardwareLibrary.MeterReaderLibrary
{
    public class MeterReaderHelper:ComHelper
    {
        public WM_Struct WMTmp = new WM_Struct();
        public double RealMeterValue;
        public virtual bool OpenWTComPort(int iPortNum, int iBaudRate, int iBeginFlag, int iEndFlag, int iStrLen, int iDataBeginFlag, int iDataLen, int iDenominatorLen, string order)
        {
            try
            {

                if (base.sPort == null)
                {
                    WMTmp.LastStableTime = DateTime.Now;//上一次的稳定时间
                    WMTmp.LastZoreTime = DateTime.Now;//上一次的归零时间
                    WMTmp.strBeginFlag = Chr(iBeginFlag);
                    WMTmp.strEndFlag = Chr(iEndFlag);
                    WMTmp.strLen = iStrLen;
                    WMTmp.DataBeginFlag = iDataBeginFlag;
                    WMTmp.DataLen = iDataLen;
                    WMTmp.DenominatorLen = iDenominatorLen;
                    WMTmp.DataOrder = order;
                    base.OpenComPortWithEventHandler(iPortNum, iBaudRate);
                }
                return base.sPort.IsOpen;
            }
            catch
            {
                return base.sPort.IsOpen;
            }
        }
        public virtual bool OpenWTComPort(int iPortNum, string strParam, int iBeginFlag, int iEndFlag, int iStrLen, int iDataBeginFlag, int iDataLen, int iDenominatorLen, string order)
        {
            try
            {

                if (base.sPort == null)
                {
                    WMTmp.LastStableTime = DateTime.Now;//上一次的稳定时间
                    WMTmp.LastZoreTime = DateTime.Now;//上一次的归零时间
                    WMTmp.strBeginFlag = Chr(iBeginFlag);
                    WMTmp.strEndFlag = Chr(iEndFlag);
                    WMTmp.strLen = iStrLen;
                    WMTmp.DataBeginFlag = iDataBeginFlag;
                    WMTmp.DataLen = iDataLen;
                    WMTmp.DenominatorLen = iDenominatorLen;
                    WMTmp.DataOrder = order;
                    base.OpenComPortWithEventHandler(iPortNum,strParam);
                }
                return base.sPort.IsOpen;
            }
            catch
            {
                return base.sPort.IsOpen;
            }
        }
        public virtual bool OpenComPortByParam(WM_Struct wm)
        {
            return OpenWTComPort(wm.iPortNum, wm.strParam, wm.iBeginFlag, wm.iEndFlag, wm.strLen, wm.DataBeginFlag, wm.DataLen, wm.DenominatorLen, wm.DataOrder);
        }
        public override void Port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                int beginIndex;
                string tmp;
                base.Port_DataReceived(sender, e);
                beginIndex = base.whatRecieved.IndexOf(WMTmp.strBeginFlag);
                if (beginIndex >= 0)//如果截取的字符串存在起始标示符
                {
                    #region 数值有效位截取
                    base.whatRecieved = base.whatRecieved.Substring(beginIndex, WMTmp.strLen);//截取规定的长度，在截取后判断末尾是否是正确的标示符
                    tmp = base.whatRecieved.Substring(WMTmp.DataBeginFlag, WMTmp.DataLen);
                    if (WMTmp.DataOrder == "正序")
                    {
                        RealMeterValue = Convert.ToDouble(tmp) / WMTmp.DenominatorLen;
                    }
                    else
                    {
                        RealMeterValue = Convert.ToDouble(Reverse(tmp)) / WMTmp.DenominatorLen;
                    }
                    #endregion
                    #region 归零判断
                    if (RealMeterValue < 0)
                    {
                        WMTmp.IsZoreFlag = false;
                    }
                    if (WMTmp.IsZoreFlag == false)
                    {
                        if (RealMeterValue == 0)
                        {
                            if (DateDiff(WMTmp.LastZoreTime, DateTime.Now) > 1)
                            {
                                WMTmp.IsZoreFlag = true;
                            }
                        }
                        else
                        {
                            WMTmp.LastZoreTime = DateTime.Now;
                        }
                    }
                    #endregion
                    #region 数值稳定性判断
                    if (RealMeterValue == WMTmp.LastStableValue)
                    {
                        if (DateDiff(WMTmp.LastStableTime, DateTime.Now) > 1)
                        {
                            WMTmp.IsStable = true;
                        }
                        else
                        {
                            WMTmp.IsStable = false;
                        }
                    }
                    else
                    {
                        WMTmp.LastStableTime = DateTime.Now;
                        WMTmp.LastStableValue = RealMeterValue;
                        WMTmp.IsStable = false;
                    }
                    #endregion
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteLog(LogFile.Error, ex.Message);
            }
        }
        public void DataReceived_Event()
        {

        }
        /// <summary>
        /// ASCII码转字符串
        /// </summary>
        /// <param name="asciiCode"></param>
        /// <returns></returns>
        private string Chr(int asciiCode)
        {
            if (asciiCode >= 0 && asciiCode <= 255)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                byte[] byteArray = new byte[] { (byte)asciiCode };
                string strCharacter = asciiEncoding.GetString(byteArray);
                return (strCharacter);
            }
            else
            {
                throw new Exception("ASCII Code is not valid.");
            }
        }
        /// <summary>
        /// 字符串翻转函数,如把ABCDEF转换成FEDCBA
        /// </summary>
        /// <param name="original"></param>
        /// <returns></returns>
        public static string Reverse(string original)
        {
            char[] arr = original.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }
        public static int DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            try
            {
                TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
                TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
                TimeSpan ts = ts1.Subtract(ts2).Duration();
                return ts.Seconds;
            }
            catch
            {
                return 0;
            }
        }
    }
}
